﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Research.Kinect.Nui;
using System.Threading;
using System.Net.Sockets;
using System.Diagnostics;
using System.Net;

namespace KinectServer
{
    public class Program
    {
        public static Runtime nui;
        public static bool running = true;
        public static KinectSkeletonFrame skeletonFrame;
        public static bool newSkeletonFrame;
        public static int fps = 30;
        public static int mspf = 1000 / fps;
        public static Stopwatch stopwatch = new Stopwatch();


        static void Main(string[] args)
        {
            Kinect(); 
            
            Server.StartServer();
        }

        private static void StartKinect()
        {
            Thread t = new Thread(new ThreadStart(Kinect));
            t.Start();
        }

        private static void Kinect()
        {
            nui = new Runtime();

            try
            {
                nui.Initialize(RuntimeOptions.UseDepth | RuntimeOptions.UseSkeletalTracking);
            }
            catch { Console.WriteLine("Failed to initialize Kinect"); }

            try
            {
                Thread.Sleep(300);
                nui.NuiCamera.ElevationAngle = -10;
                Thread.Sleep(1000);
                nui.NuiCamera.ElevationAngle = 10;
                Thread.Sleep(1000);
                nui.NuiCamera.ElevationAngle = 0;
                Thread.Sleep(300);
            }
            catch (Exception e) { 
                Console.WriteLine("Failed to change elevation.\n{0}", e.Message);
                throw new Exception("Error initializing kinect");
            }

            try
            {
                nui.DepthStream.Open(ImageStreamType.Depth, 2, ImageResolution.Resolution320x240, ImageType.Depth);
            }
            catch { Console.WriteLine("Failed to open depth stream"); }

            while (nui.SkeletonEngine == null)
            {
                Thread.Sleep(100);
            }

            try
            {
                nui.DepthFrameReady += new EventHandler<ImageFrameReadyEventArgs>(nui_DepthFrameReady);
            }
            catch { Console.WriteLine("Failed to add skeleton stream frame ready event handler"); }

            try
            {
                nui.SkeletonFrameReady += new EventHandler<SkeletonFrameReadyEventArgs>(nui_SkeletonFrameReady);
            }
            catch { Console.WriteLine("Failed to add skeleton stream frame ready event handler"); }
        }

        static void nui_DepthFrameReady(object sender, ImageFrameReadyEventArgs e)
        {
            try
            {
                if (newSkeletonFrame)
                {
                    Console.WriteLine("Sending new skeleton frame");
                    newSkeletonFrame = false;
                }
                else
                {
                    Console.WriteLine("\tImageFrame.FrameNumber: {0}", e.ImageFrame.FrameNumber);
                    skeletonFrame = new KinectSkeletonFrame(e.ImageFrame.FrameNumber, e.ImageFrame.Timestamp);
                }
            }
            catch {  }
        }

        static void nui_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
        {
            try
            {
                skeletonFrame = new KinectSkeletonFrame(e.SkeletonFrame);
                Console.WriteLine("\tSkeletonFrame.FrameNumber: {0}", skeletonFrame.FrameNumber);
                newSkeletonFrame = true;
            }
            catch { Console.WriteLine("Failed in nui_SkeletonFrameReady"); }
        }


    }
}
